package com.yanqu.road.dataHelper.action;

import com.yanqu.road.dataHelper.action.crossunion.*;
import com.yanqu.road.dataHelper.gameServer.GameServer;
import com.yanqu.road.dataHelper.manager.ServerMgr;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.union.cross.*;
import com.yanqu.road.entity.union.parergon.UnionBussinessman;
import com.yanqu.road.entity.union.parergon.UnionBussinessmanDetail;
import com.yanqu.road.entity.union.parergon.UnionParergon;
import com.yanqu.road.entity.union.parergon.UnionParergonPlayer;
import com.yanqu.road.entity.union.trade.UnionTradeTeamData;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.concurrent.*;

public class CrossUnionDataMove extends actionBase {
    protected static Logger logger = LogManager.getLogger(CrossUnionDataMove.class.getName());
    private static Map<Long, GameServer> gameServerMap = new HashMap<>();
    private final int maxCount = 50;

    public void go(List<Long> allServerList) {
        long beginTime = System.currentTimeMillis();
        ExecutorService loginExecutors = Executors.newFixedThreadPool(10);
        ThreadPoolExecutor crossDaoExectuors = (ThreadPoolExecutor)Executors.newFixedThreadPool(50);
        List<Future<Boolean>> daoFutureList = new ArrayList<>();
        long start = System.currentTimeMillis();
        for (Long serverId : allServerList) {
            List<Long> serverList = new ArrayList<>();
            serverList.add(serverId);
            List<CrossUnionInfo> allList = new ArrayList<>();
            getUnionInfoList(serverList, loginExecutors, allList);
            System.out.println("select CrossUnionInfo cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            int index = 0;
            do{
                List<CrossUnionInfo> doList;
                if(allList.size() > maxCount * index){
                    int subStart = maxCount * index;
                    int subEnd = maxCount * (index + 1);
                    if(subEnd > allList.size()){
                        subEnd = allList.size();
                    }
                    doList = allList.subList(subStart, subEnd);
                    Future<Boolean> future = crossDaoExectuors.submit((Callable<Boolean>) () -> {
                        ServerMgr serverMgr = new ServerMgr();

                        return serverMgr.addCrossUnionInfoList(doList);
                    });
                    daoFutureList.add(future);
                }else {
                    break;
                }
                index++;
            }while (true);
            System.out.println("add CrossUnionInfo record size " + allList.size());
            System.out.println("add CrossUnionInfo cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            List<CrossUnionMember> allList2 = new ArrayList<>();
            getCrossUnionMemberList(serverList, loginExecutors, allList2);
            System.out.println("select CrossUnionMember cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            index = 0;
            do{
                List<CrossUnionMember> doList;
                if(allList2.size() > maxCount * index){
                    int subStart = maxCount * index;
                    int subEnd = maxCount * (index + 1);
                    if(subEnd > allList2.size()){
                        subEnd = allList2.size();
                    }
                    doList = allList2.subList(subStart, subEnd);
                    Future<Boolean> future = crossDaoExectuors.submit((Callable<Boolean>) () -> {
                        ServerMgr serverMgr = new ServerMgr();

                        return serverMgr.addCrossUnionMemberList(doList);
                    });
                    daoFutureList.add(future);
                }else {
                    break;
                }
                index++;
            }while (true);
            System.out.println("add CrossUnionMember record size " + allList2.size());
            System.out.println("add CrossUnionMember cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            List<CrossUnionChamberPatrons> allList3 = new ArrayList<>();
            getCrossUnionChamberPatronsList(serverList, loginExecutors, allList3);
            System.out.println("select CrossUnionChamberPatrons cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            index = 0;
            do{
                List<CrossUnionChamberPatrons> doList;
                if(allList3.size() > maxCount * index){
                    int subStart = maxCount * index;
                    int subEnd = maxCount * (index + 1);
                    if(subEnd > allList3.size()){
                        subEnd = allList3.size();
                    }
                    doList = allList3.subList(subStart, subEnd);
                    Future<Boolean> future = crossDaoExectuors.submit((Callable<Boolean>) () -> {
                        ServerMgr serverMgr = new ServerMgr();

                        return serverMgr.addCrossUnionChamberPatronsList(doList);
                    });
                    daoFutureList.add(future);
                }else {
                    break;
                }
                index++;
            }while (true);
            System.out.println("add CrossUnionChamberPatrons record size " + allList3.size());
            System.out.println("add CrossUnionChamberPatrons cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            List<CrossUnionNotice> allList4 = new ArrayList<>();
            getCrossUnionNoticeList(serverList, loginExecutors, allList4);
            System.out.println("select CrossUnionNotice cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();
            index = 0;
            do{
                List<CrossUnionNotice> doList;
                if(allList4.size() > maxCount * index){
                    int subStart = maxCount * index;
                    int subEnd = maxCount * (index + 1);
                    if(subEnd > allList4.size()){
                        subEnd = allList4.size();
                    }
                    doList = allList4.subList(subStart, subEnd);
                    Future<Boolean> future = crossDaoExectuors.submit((Callable<Boolean>) () -> {
                        ServerMgr serverMgr = new ServerMgr();

                        return   serverMgr.addCrossUnionNoticeList(doList);

                    });
                    daoFutureList.add(future);
                }else {
                    break;
                }
                index++;
            }while (true);
            System.out.println("add CrossUnionNotice record size " + allList4.size());
            System.out.println("add CrossUnionNotice cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            List<CrossUnionFlag> allList5 = new ArrayList<>();
            getCrossUnionFlagList(serverList, loginExecutors, allList5);
            System.out.println("select CrossUnionFlag cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();
            index = 0;
            do{
                List<CrossUnionFlag> doList;
                if(allList5.size() > maxCount * index){
                    int subStart = maxCount * index;
                    int subEnd = maxCount * (index + 1);
                    if(subEnd > allList5.size()){
                        subEnd = allList5.size();
                    }
                    doList = allList5.subList(subStart, subEnd);
                    Future<Boolean> future = crossDaoExectuors.submit((Callable<Boolean>) () -> {
                        ServerMgr serverMgr = new ServerMgr();

                        return serverMgr.addCrossUnionFlagList(doList);
                    });
                    daoFutureList.add(future);
                }else {
                    break;
                }
                index++;
            }while (true);
            System.out.println("add CrossUnionFlag record size " + allList5.size());
            System.out.println("add CrossUnionFlag cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            List<UnionTradeTeamData> allList6 = new ArrayList<>();
            getUnionTradeTeamDataList(serverList, loginExecutors, allList6);
            System.out.println("select UnionTradeTeamData cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();
            index = 0;
            do{
                List<UnionTradeTeamData> doList;
                if(allList6.size() > maxCount * index){
                    int subStart = maxCount * index;
                    int subEnd = maxCount * (index + 1);
                    if(subEnd > allList6.size()){
                        subEnd = allList6.size();
                    }
                    doList = allList6.subList(subStart, subEnd);
                    Future<Boolean> future = crossDaoExectuors.submit((Callable<Boolean>) () -> {
                        ServerMgr serverMgr = new ServerMgr();

                        return serverMgr.addUnionTradeTeamDataList(doList);
                    });
                    daoFutureList.add(future);
                }else {
                    break;
                }
                index++;
            }while (true);
            System.out.println("add UnionTradeTeamData record size " + allList6.size());
            System.out.println("add UnionTradeTeamData cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            List<UnionParergon> allList7 = new ArrayList<>();
            getUnionParergonList(serverList, loginExecutors, allList7);
            System.out.println("select UnionParergon cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();
            index = 0;
            do{
                List<UnionParergon> doList;
                if(allList7.size() > maxCount * index){
                    int subStart = maxCount * index;
                    int subEnd = maxCount * (index + 1);
                    if(subEnd > allList7.size()){
                        subEnd = allList7.size();
                    }
                    doList = allList7.subList(subStart, subEnd);
                    Future<Boolean> future = crossDaoExectuors.submit((Callable<Boolean>) () -> {
                        ServerMgr serverMgr = new ServerMgr();

                        return serverMgr.addUnionParergonList(doList);

                    });
                    daoFutureList.add(future);
                }else {
                    break;
                }
                index++;
            }while (true);
            System.out.println("add UnionParergon record size " + allList7.size());
            System.out.println("add UnionParergon cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            List<UnionParergonPlayer> allList8 = new ArrayList<>();
            getUnionParergonPlayerList(serverList, loginExecutors, allList8);
            System.out.println("select UnionParergonPlayer cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();
            index = 0;
            do{
                List<UnionParergonPlayer> doList;
                if(allList8.size() > maxCount * index){
                    int subStart = maxCount * index;
                    int subEnd = maxCount * (index + 1);
                    if(subEnd > allList8.size()){
                        subEnd = allList8.size();
                    }
                    doList = allList8.subList(subStart, subEnd);
                    Future<Boolean> future = crossDaoExectuors.submit((Callable<Boolean>) () -> {
                        ServerMgr serverMgr = new ServerMgr();

                        return   serverMgr.addUnionParergonPlayerList(doList);

                    });
                    daoFutureList.add(future);
                }else {
                    break;
                }
                index++;
            }while (true);
            System.out.println("add UnionParergonPlayer record size " + allList8.size());
            System.out.println("add UnionParergonPlayer cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            List<UnionBussinessman> allList9 = new ArrayList<>();
            getUnionBussinessmanList(serverList, loginExecutors, allList9);
            System.out.println("select UnionBussinessman cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();
            index = 0;
            do{
                List<UnionBussinessman> doList;
                if(allList9.size() > maxCount * index){
                    int subStart = maxCount * index;
                    int subEnd = maxCount * (index + 1);
                    if(subEnd > allList9.size()){
                        subEnd = allList9.size();
                    }
                    doList = allList9.subList(subStart, subEnd);
                    Future<Boolean> future = crossDaoExectuors.submit((Callable<Boolean>) () -> {
                        ServerMgr serverMgr = new ServerMgr();

                        return serverMgr.addUnionBussinessmanList(doList);
                    });
                    daoFutureList.add(future);
                }else {
                    break;
                }
                index++;
            }while (true);
            System.out.println("add UnionBussinessman record size " + allList9.size());
            System.out.println("add UnionBussinessman cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();

            List<UnionBussinessmanDetail> allList10 = new ArrayList<>();
            getUnionBussinessmanDetailList(serverList, loginExecutors, allList10);
            System.out.println("select bussinessmanDetail cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();
            index = 0;
            do{
                List<UnionBussinessmanDetail> doList;
                if(allList10.size() > maxCount * index){
                    int subStart = maxCount * index;
                    int subEnd = maxCount * (index + 1);
                    if(subEnd > allList10.size()){
                        subEnd = allList10.size();
                    }
                    doList = allList10.subList(subStart, subEnd);
                    Future<Boolean> future = crossDaoExectuors.submit((Callable<Boolean>) () -> {
                        ServerMgr serverMgr = new ServerMgr();

                        return   serverMgr.addUnionBussinessmanDetailList(doList);
                    });
                    daoFutureList.add(future);
                }else {
                    break;
                }
                index++;
            }while (true);
            System.out.println("add bussinessmanDetail record size " + allList10.size());
            System.out.println("add bussinessmanDetail cost " + (System.currentTimeMillis() - start));
            start = System.currentTimeMillis();
        }
        for (Future<Boolean> future : daoFutureList) {
            try {
                Boolean o = future.get();
                if (!o) {
                    logger.error("======  数据插入失败  ======" );
                    System.exit(1);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        long endTime = System.currentTimeMillis();
        long costTime = endTime - beginTime;
        logger.info("=====================    " +  costTime  + "   =========================" );
        logger.info("=====================    " +  costTime  + "   =========================" );
        logger.info("=====================    " +  costTime  + "   =========================" );
        logger.info("=====================    " +  costTime  + "   =========================" );
        logger.info("=====================    " +  costTime  + "   =========================" );
        logger.info("=====================    " +  costTime  + "   =========================" );
        logger.info("=====================    " +  costTime  + "   =========================" );
        logger.info("=====================    " +  costTime  + "   =========================" );
    }

    private void getUnionInfoList(List<Long> serverList, ExecutorService executorService, List<CrossUnionInfo> allList) {
        List<Future<List<CrossUnionInfo>>> futureList = new ArrayList<>();
        for (Long serverId : serverList) {
            if (ServerMgr.getServerInfoList().containsKey(serverId)) {
                ServerInfo serverInfo = ServerMgr.getServerInfoList().get(serverId);

                CrossUnionInfoETLCaller caller = new CrossUnionInfoETLCaller(getGameServer(serverInfo));
                Future future = executorService.submit(caller);
                futureList.add(future);
            }
        }
        try {
            for (Future<List<CrossUnionInfo>> future : futureList) {
                List<CrossUnionInfo> rankData = future.get();
                allList.addAll(rankData);
            }
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }

    private synchronized GameServer getGameServer(ServerInfo serverInfo) {
        long serverId = serverInfo.getServerId();
        GameServer gameServer = gameServerMap.get(serverId);
        if (gameServer == null) {
            gameServer = new GameServer(serverInfo);
            gameServerMap.put(serverId, gameServer);
        }
        return gameServer;
    }

    private void getCrossUnionMemberList(List<Long> serverList, ExecutorService executorService, List<CrossUnionMember> allList) {
        List<Future<List<CrossUnionMember>>> futureList = new ArrayList<>();
        for (Long serverId : serverList) {
            if (ServerMgr.getServerInfoList().containsKey(serverId)) {
                ServerInfo serverInfo = ServerMgr.getServerInfoList().get(serverId);

                CrossUnionMemberETLCaller caller = new CrossUnionMemberETLCaller(getGameServer(serverInfo));
                Future future = executorService.submit(caller);
                futureList.add(future);
            }
        }
        try {
            for (Future<List<CrossUnionMember>> future : futureList) {
                List<CrossUnionMember> rankData = future.get();
                allList.addAll(rankData);
            }
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }

    private void getCrossUnionChamberPatronsList(List<Long> serverList, ExecutorService executorService, List<CrossUnionChamberPatrons> allList) {
        List<Future<List<CrossUnionChamberPatrons>>> futureList = new ArrayList<>();
        for (Long serverId : serverList) {
            if (ServerMgr.getServerInfoList().containsKey(serverId)) {
                ServerInfo serverInfo = ServerMgr.getServerInfoList().get(serverId);

                CrossUnionChamberPatronsETLCaller caller = new CrossUnionChamberPatronsETLCaller(getGameServer(serverInfo));
                Future future = executorService.submit(caller);
                futureList.add(future);
            }
        }
        try {
            for (Future<List<CrossUnionChamberPatrons>> future : futureList) {
                List<CrossUnionChamberPatrons> rankData = future.get();
                allList.addAll(rankData);
            }
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }

    private void getCrossUnionNoticeList(List<Long> serverList, ExecutorService executorService, List<CrossUnionNotice> allList) {
        List<Future<List<CrossUnionNotice>>> futureList = new ArrayList<>();
        for (Long serverId : serverList) {
            if (ServerMgr.getServerInfoList().containsKey(serverId)) {
                ServerInfo serverInfo = ServerMgr.getServerInfoList().get(serverId);

                CrossUnionNoticeETLCaller caller = new CrossUnionNoticeETLCaller(getGameServer(serverInfo));
                Future future = executorService.submit(caller);
                futureList.add(future);
            }
        }
        try {
            for (Future<List<CrossUnionNotice>> future : futureList) {
                List<CrossUnionNotice> rankData = future.get();
                allList.addAll(rankData);
            }
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }

    private void getCrossUnionFlagList(List<Long> serverList, ExecutorService executorService, List<CrossUnionFlag> allList) {
        List<Future<List<CrossUnionFlag>>> futureList = new ArrayList<>();
        for (Long serverId : serverList) {
            if (ServerMgr.getServerInfoList().containsKey(serverId)) {
                ServerInfo serverInfo = ServerMgr.getServerInfoList().get(serverId);

                CrossUnionFlagETLCaller caller = new CrossUnionFlagETLCaller(getGameServer(serverInfo));
                Future future = executorService.submit(caller);
                futureList.add(future);
            }
        }
        try {
            for (Future<List<CrossUnionFlag>> future : futureList) {
                List<CrossUnionFlag> rankData = future.get();
                allList.addAll(rankData);
            }
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }

    private void getUnionTradeTeamDataList(List<Long> serverList, ExecutorService executorService, List<UnionTradeTeamData> allList) {
        List<Future<List<UnionTradeTeamData>>> futureList = new ArrayList<>();
        for (Long serverId : serverList) {
            if (ServerMgr.getServerInfoList().containsKey(serverId)) {
                ServerInfo serverInfo = ServerMgr.getServerInfoList().get(serverId);

                CrossUnionTradeTeamDataETLCaller caller = new CrossUnionTradeTeamDataETLCaller(getGameServer(serverInfo));
                Future future = executorService.submit(caller);
                futureList.add(future);
            }
        }
        try {
            for (Future<List<UnionTradeTeamData>> future : futureList) {
                List<UnionTradeTeamData> rankData = future.get();
                allList.addAll(rankData);
            }
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }

    private void getUnionParergonList(List<Long> serverList, ExecutorService executorService, List<UnionParergon> allList) {
        List<Future<List<UnionParergon>>> futureList = new ArrayList<>();
        for (Long serverId : serverList) {
            if (ServerMgr.getServerInfoList().containsKey(serverId)) {
                ServerInfo serverInfo = ServerMgr.getServerInfoList().get(serverId);

                CrossUnionParergonETLCaller caller = new CrossUnionParergonETLCaller(getGameServer(serverInfo));
                Future future = executorService.submit(caller);
                futureList.add(future);
            }
        }
        try {
            for (Future<List<UnionParergon>> future : futureList) {
                List<UnionParergon> rankData = future.get();
                allList.addAll(rankData);
            }
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }

    private void getUnionParergonPlayerList(List<Long> serverList, ExecutorService executorService, List<UnionParergonPlayer> allList) {
        List<Future<List<UnionParergonPlayer>>> futureList = new ArrayList<>();
        for (Long serverId : serverList) {
            if (ServerMgr.getServerInfoList().containsKey(serverId)) {
                ServerInfo serverInfo = ServerMgr.getServerInfoList().get(serverId);

                CrossUnionParergonPlayerETLCaller caller = new CrossUnionParergonPlayerETLCaller(getGameServer(serverInfo));
                Future future = executorService.submit(caller);
                futureList.add(future);
            }
        }
        try {
            for (Future<List<UnionParergonPlayer>> future : futureList) {
                List<UnionParergonPlayer> rankData = future.get();
                allList.addAll(rankData);
            }
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }

    private void getUnionBussinessmanList(List<Long> serverList, ExecutorService executorService, List<UnionBussinessman> allList) {
        List<Future<List<UnionBussinessman>>> futureList = new ArrayList<>();
        for (Long serverId : serverList) {
            if (ServerMgr.getServerInfoList().containsKey(serverId)) {
                ServerInfo serverInfo = ServerMgr.getServerInfoList().get(serverId);

                CrossUnionBussinessmanETLCaller caller = new CrossUnionBussinessmanETLCaller(getGameServer(serverInfo));
                Future future = executorService.submit(caller);
                futureList.add(future);
            }
        }
        try {
            for (Future<List<UnionBussinessman>> future : futureList) {
                List<UnionBussinessman> rankData = future.get();
                allList.addAll(rankData);
            }
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }

    private void getUnionBussinessmanDetailList(List<Long> serverList, ExecutorService executorService, List<UnionBussinessmanDetail> allList) {
        List<Future<List<UnionBussinessmanDetail>>> futureList = new ArrayList<>();
        for (Long serverId : serverList) {
            if (ServerMgr.getServerInfoList().containsKey(serverId)) {
                ServerInfo serverInfo = ServerMgr.getServerInfoList().get(serverId);

                CrossUnionBussinessmanDetailETLCaller caller = new CrossUnionBussinessmanDetailETLCaller(getGameServer(serverInfo));
                Future future = executorService.submit(caller);
                futureList.add(future);
            }
        }
        try {
            for (Future<List<UnionBussinessmanDetail>> future : futureList) {
                List<UnionBussinessmanDetail> rankData = future.get();
                allList.addAll(rankData);
            }
        }catch (Exception e){
            e.printStackTrace(System.out);
        }
    }
}
